import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:signage/app/data/models/cast_record_model.dart';
import 'package:signage/app/data/models/member_group_model.dart';
import 'package:signage/app/data/models/template_model.dart';
import 'package:signage/app/modules/device/models/device_cached_info.dart';
import 'package:signage/app/modules/profile/transfer/controllers/transfer_controller.dart';
import 'package:signage/app/utils/sp_util.dart';
import 'package:signage/l10n/l10n.dart';
import 'package:signage/widgets/edit_dialog.dart';
import 'package:uuid/uuid.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import '../models/device_progress.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/widgets.dart';
import 'package:signage/app/services/bluetooth_service.dart';
import 'dart:convert';

class CastProgressController extends GetxController
    with WidgetsBindingObserver {
  final BluetoothManager bluetoothService = Get.find<BluetoothManager>();
  final deviceProgress = <DeviceProgress>[].obs;
  TemplateModel? templateA;
  TemplateModel? templateB;
  int castMode = 0; // 0: A面, 1: B面, 2: 双面
  static const int MAX_RETRIES = 3;
  static const Duration CONNECT_TIMEOUT = Duration(seconds: 15);
  static const Duration OPERATION_TIMEOUT = Duration(seconds: 10);
  static const platform = MethodChannel('com.signage.signage/l2cap');
  final _progressSubscriptions = <String, Timer>{};
  final _isMonitoring = <String, bool>{};
  bool _isDisposing = false; // 添加处置标志
  static int MAX_CONCURRENT_TRANSFERS = 3; // 最大同时传输数
  final _transferQueue = <DeviceProgress>[];
  final _activeTransfers = <String>{};
  List<MemberItem> selectedMembers = [];
  String meetingTitle = '';
  CastRecord? castRecord;
  List<DeviceCachedInfo> deviceList = <DeviceCachedInfo>[];
  int groupId = 0;
  String groupName = '';
  // 添加计数器
  final successCount = 0.obs;
  final failureCount = 0.obs;
  bool isClear = false;
  // 添加一个标志来追踪控制器状态
  bool _isDisposed = false;
  @override
  Future<void> onInit() async {
    super.onInit();
    WidgetsBinding.instance.addObserver(this);

    // Ensure all existing Bluetooth connections are closed before starting
    await _disconnectAllDevices();

    // 从Get参数中获取设备列表和模板信息
    final args = Get.arguments;
    if (args != null) {
      isClear = args['isClear'] ?? false;
      templateA = args['templateA'];
      templateB = args['templateB'];
      castMode = args['castMode'] ?? 0;
      meetingTitle = args['meetingTitle'] ?? '';
      deviceList = args['devices'] ?? [];
      selectedMembers = args['members'] ?? [];
      groupId = args['groupId'] ?? 0;
      groupName = args['groupName'] ?? '';
      // 确保 deviceList 和 selectedMembers 长度一致
      deviceProgress.value = List<DeviceProgress>.generate(
        deviceList.length,
        (index) => DeviceProgress(
          deviceCachedInfo: deviceList[index],
          progress: 0.0.obs,
          status: '准备中'.obs,
          selectedMember:
              index < selectedMembers.length ? selectedMembers[index] : null,
        ),
      );
    }
    WakelockPlus.enable();
    MAX_CONCURRENT_TRANSFERS =
        SpUtil.getInt(TransferController.maxConnectionsKey) ?? 1;

    if (FlutterBluePlus.isScanningNow) {
      await bluetoothService.stopScan();
    }
    if (Platform.isAndroid) {
      if (!await isIgnoringBatteryOptimizations()) {
        Get.dialog(TipsDialog(
            title: AppLocalizations.of(Get.context!)!.translate('tips'),
            text: AppLocalizations.of(Get.context!)!
                .translate('please_allow_background_running'),
            onConfirm: () async {
              Get.back();
              await requestIgnoreBatteryOptimizations();
              startCasting();
            }));
      } else {
        startCasting();
      }
    } else {
      startCasting();
    }
    //  print(
    //     'requestIgnoreBatteryOptimizations: ${await isIgnoringBatteryOptimizations()}');
    // startCasting();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      // _cleanupResources('App state changed to: $state');
    }
  }

  Future<void> startCasting() async {
    // 将所有设备添加到队列
    _transferQueue.addAll(deviceProgress);

    // 开始处理队列
    await _processQueue();
  }

  Future<void> _processQueue() async {
    while (_transferQueue.isNotEmpty && !_isDisposed) {
      if (_activeTransfers.length < MAX_CONCURRENT_TRANSFERS) {
        final device = _transferQueue.removeAt(0);
        _activeTransfers.add(device.deviceCachedInfo.id);
        unawaited(_processDevice(device));
      }
      await Future.delayed(const Duration(milliseconds: 100));
    }
  }

  Future<void> _processDevice(DeviceProgress device) async {
    try {
      final isSuccess = await processCasting(device);
      if (isSuccess) {
        successCount.value++;
      } else {
        failureCount.value++;
      }
    } finally {
      _activeTransfers.remove(device.deviceCachedInfo.id);
      // 处理完成后继续处理队列
      if (_transferQueue.isNotEmpty) {
        unawaited(_processQueue());
      } else {
        if (!isClear) {
          castRecord = CastRecord(
            timestamp: DateTime.now(),
            success: deviceList.length == successCount.value,
            meetingTitle: meetingTitle,
            successCount: successCount.value,
            failureCount: failureCount.value,
            castMode: castMode,
            templateA: templateA,
            templateB: templateB,
            id: Uuid().v4(),
            deviceInfos: deviceList,
            memberInfos: selectedMembers,
            groupId: groupId,
            groupName: groupName,
          );
          // 更新 SharedPreferences 中的castRecord
          final existingRecords = SpUtil.getStringList('cast_records') ?? [];
          existingRecords.add(jsonEncode(castRecord!.toJson()));
          await SpUtil.setStringList('cast_records', existingRecords);
        }
      }
    }
  }

  Future<bool> processCasting(DeviceProgress device) async {
    // 在开始处添加检查
    if (_isDisposed) {
      print('Controller is disposed, stopping process');
      return false;
    }

    int retryCount = 0;
    const maxRetries = 3;
    const retryDelay = Duration(seconds: 20);

    while (retryCount < maxRetries && !_isDisposed) {
      try {
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('generating_template');
        final deviceInfoResult = device.deviceCachedInfo;

        // Process templates and get file paths
        if (isClear) {
          final filePath = await processTemplate(
              device,
              TemplateModel(
                  id: 'clear',
                  name: '一键清屏',
                  category: '清屏',
                  filePath: 'clear',
                  categoryType: 'clear'),
              1);
          final isSuccess =
              await sendFileOverBluetooth(device, filePath, filePath);
          if (!isSuccess) {
            throw Exception(AppLocalizations.of(Get.context!)!
                .translate('clear_screen_failed'));
          }
        } else if (deviceInfoResult.displayInfo.length == 1) {
          if (templateA == null) throw Exception('没有可用的模板');
          final filePath = await processTemplate(device, templateA!, 0);
          final isSuccess = await sendFileOverBluetooth(device, filePath, "");
          if (!isSuccess) {
            throw Exception('A面传输失败');
          }
        } else {
          switch (castMode) {
            case 2: // A面
              if (templateA == null) throw Exception('没有可用的A面模板');

              List<String> valueList = [];

              if (device.selectedMember?.valueBList.isNotEmpty ?? false) {
                // 处理 B 面数据
                valueList = device.selectedMember?.valueBList ?? [];
              }
              if (device.selectedMember?.valueAList.isNotEmpty ?? false) {
                // 处理 A 面数据
                valueList = device.selectedMember?.valueAList ?? [];
              }
              final filePath = await processTemplate(device, templateA!, 0,
                  textList: valueList);
              final isSuccess =
                  await sendFileOverBluetooth(device, filePath, "");
              if (!isSuccess) {
                throw Exception('A面传输失败');
              }
              break;
            case 0: // A B 同面
              if (templateA == null) throw Exception('没有可用的A面模板');
              List<String> valueList = [];
              if (device.selectedMember?.valueBList.isNotEmpty ?? false) {
                valueList = device.selectedMember?.valueBList ?? [];
              }
              if (device.selectedMember?.valueAList.isNotEmpty ?? false) {
                valueList = device.selectedMember?.valueAList ?? [];
              }
              print('valueList: $valueList');
              final filePath = await processTemplate(device, templateA!, 0,
                  textList: valueList);
              final isSuccess =
                  await sendFileOverBluetooth(device, filePath, '');
              if (!isSuccess) {
                throw Exception('A面传输失败');
              }
              break;
            case 3: // B面
              if (templateB == null) throw Exception('没有可用的B面模板');

              List<String> valueList = [];
              if (device.selectedMember?.valueAList.isNotEmpty ?? false) {
                // 处理 A 面数据
                valueList = device.selectedMember?.valueAList ?? [];
              }
              if (device.selectedMember?.valueBList.isNotEmpty ?? false) {
                // 处理 B 面数据
                valueList = device.selectedMember?.valueBList ?? [];
              }
              final filePath = await processTemplate(device, templateB!, 1,
                  textList: valueList);
              final isSuccess =
                  await sendFileOverBluetooth(device, "", filePath);
              if (!isSuccess) {
                throw Exception('B面传输失败');
              }
              break;
            case 1: // 双面
              if (templateA == null) throw Exception('没有可用的A面模板');
              if (templateB == null) throw Exception('没有可用的B面模板');

              final filePathA = await processTemplate(device, templateA!, 0,
                  textList: device.selectedMember?.valueAList);
              final filePathB = await processTemplate(device, templateB!, 1,
                  textList: device.selectedMember?.valueBList);
              final isSuccess =
                  await sendFileOverBluetooth(device, filePathA, filePathB);
              if (!isSuccess) {
                throw Exception('双面传输失败');
              }
              break;
            default:
              return false;
          }
        }

        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('success');
        return true;
      } catch (e) {
        if (_isDisposed) {
          print('Controller is disposed, stopping retry');
          return false;
        }
        retryCount++;
        print('投屏错误 (尝试 $retryCount/$maxRetries): ${e.toString()}');
        device.progress.value = 0.0;
        if (retryCount < maxRetries) {
          device.status.value = AppLocalizations.of(Get.context!)!
              .translate('retrying_connection')
              .replaceAll('{count}', '$retryCount/$maxRetries');
          await Future.delayed(retryDelay * retryCount); // Exponential backoff
          continue;
        }

        device.status.value =
            '${AppLocalizations.of(Get.context!)!.translate('failed')}: $e (${AppLocalizations.of(Get.context!)!.translate('retried')} $maxRetries ${AppLocalizations.of(Get.context!)!.translate('times')})';
        return false;
      }
    }
    return false;
  }

  Future<String> processTemplate(
      DeviceProgress device, TemplateModel template, int displayIndex,
      {List<String>? textList}) async {
    try {
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('generating_template');

      // Get device display info
      final displayInfo = device.deviceCachedInfo.displayInfo[displayIndex];

      // Generate unique filename using template id and timestamp
      final fileName =
          '${template.id}_${DateTime.now().millisecondsSinceEpoch}.bin';
      print('fileName: $fileName');
      print('displayInfo: $displayInfo');
      print('textList: $textList');
      print('isClear: $isClear');
      print('template: ${template.toJson()}');
      // Convert template to e-paper format
      final filePath = await template.convertToEpaper(
        fileName,
        displayInfo.displayType,
        width: displayInfo.width,
        height: displayInfo.height,
        textList: textList,
        isClear: isClear,
      );

      if (filePath == null) {
        throw Exception('模板转失败');
      }

      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('template_generated');
      return filePath;
    } catch (e) {
      print('模板处理错误: $e');
      throw Exception('模板处理失败');
    }
  }

  Future<bool> sendFileOverBluetooth(
      DeviceProgress device, String filePathA, String filePathB) async {
    BluetoothDevice? bluetoothDevice;
    try {
      // 1. 连接设备（包含重试逻辑）
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('connecting_device');
      bluetoothDevice = BluetoothDevice.fromId(device.deviceCachedInfo.id);

      // Make sure to disconnect first if already connected
      if (bluetoothDevice.isConnected) {
        print('设备已连接，先断开: ${device.deviceCachedInfo.id}');
        await _closeL2capChannel(bluetoothDevice);
        await bluetoothDevice.disconnect();
        await Future.delayed(const Duration(milliseconds: 500));
      }

      for (int retry = 0; retry < MAX_RETRIES; retry++) {
        try {
          if (!bluetoothDevice.isConnected) {
            await bluetoothDevice.connect(timeout: CONNECT_TIMEOUT);
            bluetoothService
                    .deviceInfoMap[device.deviceCachedInfo.id.toString()] =
                bluetoothService
                    .deviceInfoMap[device.deviceCachedInfo.id.toString()]!
                    .copyWith(connectedTime: DateTime.now());
          }
          break;
        } catch (e) {
          if (retry == MAX_RETRIES - 1)
            throw Exception('连接失败，已重试$MAX_RETRIES次');
          device.status.value = AppLocalizations.of(Get.context!)!
              .translate('retrying_connection')
              .replaceAll('{count}', '${retry + 1}/$MAX_RETRIES');
          await Future.delayed(const Duration(seconds: 2));
        }
      }
      // 2. 发现服务
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('initializing_service');
      final services = await bluetoothDevice.discoverServices();

      // 3. 获取所需特征值
      final olcpCharacteristic = services
          .expand((s) => s.characteristics)
          .firstWhere((c) => c.uuid.toString().toLowerCase() == '2ac6',
              orElse: () => throw Exception('找不到OLCP特征值(2AC6)'));

      final opsCharacteristic = services
          .expand((s) => s.characteristics)
          .firstWhere((c) => c.uuid.toString().toLowerCase() == '2ac5',
              orElse: () => throw Exception('找不到OPS特征值(2AC5)'));

      // 4. 设置特征值通知
      device.status.value = AppLocalizations.of(Get.context!)!
          .translate('initializing_notification');
      await olcpCharacteristic.setNotifyValue(true);
      await opsCharacteristic.setNotifyValue(true);
      await Future.delayed(const Duration(milliseconds: 100));

      // 创建L2CAP通道（只需要创建一次）
      await _createL2capChannel(bluetoothDevice, 0x0025);
      await Future.delayed(const Duration(seconds: 2));

      // 处理A面传输
      if (filePathA.isNotEmpty ||
          (isClear && device.deviceCachedInfo.displayInfo.isNotEmpty)) {
        // 5a. 选择A面对象
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('selecting_side_a');
        final selectObjectCommandA = writeOLCP(0x05, 0x000000000100);
        await olcpCharacteristic.write(selectObjectCommandA);
        await Future.delayed(const Duration(milliseconds: 100));

        // 6a. 准备A面文件数据
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('preparing_side_a');
        final bytesA = await File(filePathA).readAsBytes();
        print('A面文件大小: ${bytesA.length}');

        // 7a. 发送A面文件大小命令并等待响应
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('sending_side_a_info');
        final sizeCommandResponseA = await _sendSizeCommandAndWaitResponse(
            opsCharacteristic, bytesA.length, bluetoothDevice);
        if (!sizeCommandResponseA) {
          throw Exception('A面文件大小命令响应超时');
        }

        final services = await bluetoothDevice.discoverServices();
        // 8a. 传输A面数据
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('transferring_side_a');
        // unawaited(_monitorProgress(progressCharacteristic, device)
        //     .catchError((error) {}));

        final progressCharacteristic = services
            .expand((s) => s.characteristics)
            .firstWhere(
                (c) =>
                    c.uuid.toString().toLowerCase() ==
                    'aa2e7828-fbce-4e01-ae9e-261174997c49',
                orElse: () => throw Exception('找不到进度特征值'));

        // 监听进度通知
        final subscription =
            progressCharacteristic.onValueReceived.listen((value) {
          // 处理进度值
          print('🔍 进度值 ${device.deviceCachedInfo.id}: $value');
          final progress = value[0] / 100; // 假设进度值在第一个字节
          if (progress != 0) {
            device.progress.value = progress;
          }
        });
        bluetoothDevice.cancelWhenDisconnected(subscription);

        // 启用通知
        await progressCharacteristic.setNotifyValue(true);

        await Future.delayed(const Duration(milliseconds: 500));
        await _sendDataViaL2CAP(bluetoothDevice, bytesA);

        var waitTime = 0;
        // 等待A面传输完成
        while (device.progress.value < 1.0) {
          waitTime += 500;
          await Future.delayed(const Duration(milliseconds: 500));

          if (waitTime > (bytesA.length > 96000 ? 200000 : 20000)) {
            throw Exception('读取进度失败');
          }
        }
      }

      // 处理B面传输
      if (filePathB.isNotEmpty && !isClear) {
        // 重置进度
        if (filePathA.isNotEmpty) {
          await Future.delayed(const Duration(milliseconds: 5000));
        }

        // 5b. 选择B面对象
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('selecting_side_b');
        final selectObjectCommandB = writeOLCP(0x05, 0x000000000101);
        await olcpCharacteristic.write(selectObjectCommandB);
        await Future.delayed(const Duration(milliseconds: 100));
        device.progress.value = 0.0;
        // 6b. 准备B面文件数据
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('preparing_side_b');
        final bytesB = await File(filePathB).readAsBytes();
        print('B面文件大小: ${bytesB.length}');

        // 7b. 发送B面文件大小命令并等待响应
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('sending_side_b_info');
        final sizeCommandResponseB = await _sendSizeCommandAndWaitResponse(
            opsCharacteristic, bytesB.length, bluetoothDevice);
        if (!sizeCommandResponseB) {
          throw Exception('B面文件大小命令响应超时');
        }
        final services = await bluetoothDevice.discoverServices();
        final progressCharacteristic = services
            .expand((s) => s.characteristics)
            .firstWhere(
                (c) =>
                    c.uuid.toString().toLowerCase() ==
                    'aa2e7828-fbce-4e01-ae9e-261174997c49',
                orElse: () => throw Exception('找不到进度特征值'));
        // 8b. 传输B面数据
        device.status.value =
            AppLocalizations.of(Get.context!)!.translate('transferring_side_b');

        // unawaited(_monitorProgress(progressCharacteristic, device)
        //     .catchError((error) {
        //   // 可以添加额外的错误处理逻辑
        // }));


        // 监听进度通知
        final subscription =
            progressCharacteristic.onValueReceived.listen((value) {
          // 处理进度值
          print('🔍 进度值 ${device.deviceCachedInfo.id}: $value');
          final progress = value[0] / 100; // 假设进度值在第一个字节
          if (progress != 0) {
            device.progress.value = progress;
          }
        });

        bluetoothDevice.cancelWhenDisconnected(subscription);

        // 启用通知
        await progressCharacteristic.setNotifyValue(true);

        await Future.delayed(const Duration(milliseconds: 500));

        await _sendDataViaL2CAP(bluetoothDevice, bytesB);

        // 等待B面传输完成
        var waitTime = 0;
        // 等待A面传输完成
        while (device.progress.value < 1.0) {
          waitTime += 500;
          await Future.delayed(const Duration(milliseconds: 500));

          if (waitTime > (bytesB.length > 96000 ? 200000 : 20000)) {
            throw Exception('读取进度失败');
          }
        }
      }
// 根据castMode和文件情况决定显示方式
      Uint8List displayCommand;
      print('castMode: $castMode');
      switch (castMode) {
        case 0: // A B同面
          // 双屏显示相同画面
          displayCommand = executeDisplayControl(
            screenAObjectId: 0x000000000100,
            screenBObjectId: 0x000000000100,
          );
          break;

        case 1: // 双面
          // 双屏显示不同画面
          displayCommand = executeDisplayControl(
            screenAObjectId: 0x000000000100,
            screenBObjectId: 0x000000000101,
          );
          break;

        case 2: // 仅A面
          // 只更新A屏
          displayCommand = executeDisplayControl(
            screenAObjectId: 0x000000000100,
            screenBObjectId: 0x000000000000,
          );
          break;

        case 3: // 仅B面
          // 只更新B屏
          displayCommand = executeDisplayControl2(0x0001, 0x000000000101);
          print(
              '显示命令内容: ${displayCommand.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' ')}');
          break;

        default:
          throw Exception('无效的显示模式');
      }

      if (isClear) {
        if (device.deviceCachedInfo.displayInfo.isNotEmpty &&
            device.deviceCachedInfo.displayInfo.length > 1) {
          displayCommand = executeDisplayControl(
            screenAObjectId: 0x000000000100,
            screenBObjectId: 0x000000000100,
          );
        } else {
          displayCommand = executeDisplayControl(
            screenAObjectId: 0x000000000100,
            screenBObjectId: 0x000000000000,
          );
        }
      }

      // 发送显示命令
      await opsCharacteristic.write(displayCommand);
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('success');

      return true;
    } catch (e) {
      print('传输错误: $e');
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('failed');
      return false;
    } finally {
      // 确保清理监控
      await _cancelProgressMonitoring(device.deviceCachedInfo.id);

      // Ensure disconnection even if bluetoothDevice is null
      if (bluetoothDevice != null) {
        try {
          print('断开设备连接: ${device.deviceCachedInfo.id}');
          await _closeL2capChannel(bluetoothDevice);
          await Future.delayed(const Duration(milliseconds: 300));
          await bluetoothDevice.disconnect();
          // Verify disconnection
          await Future.delayed(const Duration(milliseconds: 300));
          if (bluetoothDevice.isConnected) {
            print('Warning: Device still connected after disconnect attempt');
            // Try one more time
            await bluetoothDevice.disconnect();
          }
        } catch (e) {
          print('断开连接错误: $e');
        }
      }
    }
  }

  Future<void> _sendDataViaL2CAP(BluetoothDevice device, Uint8List data) async {
    try {
      await platform.invokeMethod('sendL2capData', {
        'deviceId': device.id.toString(),
        'data': data,
      });
    } catch (e) {
      print('L2CAP send error: $e');
      rethrow;
    }
  }

  Future<void> _createL2capChannel(BluetoothDevice device, int psm) async {
    try {
      await platform.invokeMethod('createL2capChannel', {
        'deviceId': device.id.toString(),
        'psm': psm,
      });
    } catch (e) {
      print('L2CAP channel creation error: $e');
      rethrow;
    }
  }

  Future<void> _closeL2capChannel(BluetoothDevice? device) async {
    if (device == null) return;

    try {
      print('Closing L2CAP channel for device: ${device.id}');
      await platform.invokeMethod('closeL2capChannel', {
        'deviceId': device.id.toString(),
      });
    } catch (e) {
      print('L2CAP channel close error: $e');
      // Don't rethrow to ensure cleanup continues
    }
  }

  Future<void> requestIgnoreBatteryOptimizations() async {
    try {
      await platform.invokeMethod('requestIgnoreBatteryOptimizations', {});
    } catch (e) {
      print('L2CAP MTU set error: $e');
      rethrow;
    }
  }

  Future<bool> isIgnoringBatteryOptimizations() async {
    try {
      final result =
          await platform.invokeMethod('isIgnoringBatteryOptimizations');
      return result ?? false;
    } catch (e) {
      print('Error checking battery optimizations: $e');
      return false;
    }
  }

  Future<Map<String, dynamic>> getL2capMtu(BluetoothDevice? device) async {
    try {
      final result = await platform.invokeMethod('getL2capMtu', {
        'deviceId': device?.id.toString(),
      });

      print('L2CAP MTU Info: $result');
      return Map<String, dynamic>.from(result);
    } catch (e) {
      print('Error getting L2CAP MTU: $e');
      rethrow;
    }
  }

  // 辅助方法：发送大小命令并等待响应
  Future<bool> _sendSizeCommandAndWaitResponse(
    BluetoothCharacteristic opsCharacteristic,
    int fileSize,
    BluetoothDevice bluetoothDevice,
  ) async {
    final completer = Completer<bool>();
    StreamSubscription? subscription;

    subscription = opsCharacteristic.onValueReceived.listen((value) {
      print('收到opsCharacteristic指令${value}');
      if (value.length >= 3 &&
          value[0] == 0x60 &&
          value[1] == 0x06 &&
          value[2] == 0x01) {
        subscription?.cancel();
        completer.complete(true);
      }
    });
    bluetoothDevice.cancelWhenDisconnected(subscription);
    print('实际文件大小: ${fileSize}'); // 验证文件大小
    final sizeCommand = writeOACP(0, fileSize, 0);
    await opsCharacteristic.write(sizeCommand, withoutResponse: false);
    try {
      return await completer.future.timeout(OPERATION_TIMEOUT);
    } catch (e) {
      return false;
    }
  }

  // Add new method to handle reconnection
  Future<void> _handleReconnection(DeviceProgress device) async {
    if (device.progress.value == 1.0) {
      return;
    }
    await _cancelProgressMonitoring(device.deviceCachedInfo.id);
    device.status.value = AppLocalizations.of(Get.context!)!
        .translate('reconnecting_in')
        .replaceAll('{seconds}', '30');

    // 1. 确保清理现有连接
    final bluetoothDevice = BluetoothDevice.fromId(device.deviceCachedInfo.id);
    await _cleanupConnection(device, bluetoothDevice);

    // 2. 等待设备重置
    await Future.delayed(const Duration(seconds: 2));

    // 3. 重新建立基本连接
    // await _establishConnection(device, bluetoothDevice);

    // 4. 重新开始投放流程
    await processCasting(device);
  }

  Future<void> _cleanupConnection(
      DeviceProgress device, BluetoothDevice bluetoothDevice) async {
    try {
      await _closeL2capChannel(bluetoothDevice);
      await bluetoothDevice.disconnect();
      for (int i = 30; i > 0; i--) {
        device.status.value = AppLocalizations.of(Get.context!)!
            .translate('reconnecting_in')
            .replaceAll('{seconds}', '$i');
        await Future.delayed(const Duration(seconds: 1));
      }
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('reconnecting');
    } catch (e) {
      print('清理连接时出错: $e');
      // 继续执行，不抛出异常
    }
  }

  Future<void> _establishConnection(
      DeviceProgress device, BluetoothDevice bluetoothDevice) async {
    int retryCount = 0;
    const maxRetries = 3;

    while (retryCount < maxRetries) {
      try {
        // 1. 建立基本蓝牙连接
        await bluetoothDevice.connect(
          timeout: const Duration(seconds: 10),
          autoConnect: false,
        );
        bluetoothService.deviceInfoMap[bluetoothDevice.remoteId.toString()] =
            bluetoothService.deviceInfoMap[bluetoothDevice.remoteId.toString()]!
                .copyWith(connectedTime: DateTime.now());

        // 2. 等待连接稳定
        await Future.delayed(const Duration(seconds: 1));

        // 3. 尝试创建 L2CAP 通道
        for (int i = 0; i < 3; i++) {
          try {
            await _createL2capChannel(bluetoothDevice, 0x0025);
            print('L2CAP 通道创建成功');
            return; // 成功则直接返回
          } catch (e) {
            print('L2CAP 通道创建失败 (尝试 ${i + 1}/3): $e');
            if (i < 2) {
              await Future.delayed(const Duration(seconds: 1));
            } else {
              throw e; // 最后一次尝试失败时抛出异常
            }
          }
        }
      } catch (e) {
        retryCount++;
        print('连接尝试 $retryCount 失败: $e');
        device.status.value = '连接尝试 $retryCount';
        if (retryCount >= maxRetries) {
          throw Exception('重连失败，已达到最大重试次数');
        }

        // 重试前等待
        await Future.delayed(Duration(seconds: retryCount * 2));
      }
    }
  }

  void _handleReconnectionError(DeviceProgress device, dynamic error) {
    device.progress.value = 0.0;

    if (error.toString().contains('CONNECTION_ERROR')) {
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('check_device_range');
    } else if (error.toString().contains('TIMEOUT')) {
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('connection_timeout');
    } else {
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('failed') + ': $error';
    }

    // 记录详细错误信息
    print('重连失败详细信息: $error');
  }

  // 添加取消监控的方法
  Future<void> _cancelProgressMonitoring(String deviceId) async {
    _isMonitoring[deviceId] = false;
    final timer = _progressSubscriptions.remove(deviceId);
    if (timer != null) {
      timer.cancel();
      print('Cancelled progress monitoring for device: $deviceId');
    }
  }

  // 从网拉取文件并返回二进制数据
  Future<List<int>> _fetchFileFromUrl(String url) async {
    try {
      final response = await http.get(Uri.parse(url));
      print("下载文件：status${response.statusCode},${response.body}");
      if (response.statusCode == 200) {
        return response.bodyBytes; // 按照起始地址偏移解析数据
      } else {
        throw Exception("下载文件失败，状态码: ${response.statusCode}");
      }
    } catch (e) {
      throw Exception("下载文件出错: $e");
    }
  }

  Uint8List writeOLCP(int command, int objectId) {
    // 初始化一个 Uint8List 用于存储生成的二进制数据
    Uint8List data = Uint8List(7); // 1字节命令 + 6字节 object_id = 7字节

    // 第一个字节是命令
    data[0] = command;

    // 将 object_id 分成 6 字节小端序存入数组，从 data 的第 1 个字节开始
    for (int i = 0; i < 6; i++) {
      data[i + 1] = (objectId >> (8 * i)) & 0xFF; // 小端序，低位字节在前
    }
    print(
        'OLCP command hex: ${data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' ')}');

    print('data: $data');
    return data;
  }

  Uint8List writeOACP(int offset, int length, int mode) {
    int commandType = 0x06;

    // 创建合适大小的数据包（10 个字节）
    Uint8List data = Uint8List(10);
    ByteData buffer = ByteData.view(data.buffer);

    // 使用 ByteData 直接写入，确保字节序正确
    buffer.setUint8(0, commandType);
    buffer.setUint32(1, offset, Endian.little); // offset 4字节
    buffer.setUint32(5, length, Endian.little); // length 4字节
    buffer.setUint8(9, mode);

    // 调信息
    print('Length in hex: 0x${length.toRadixString(16)}'); // 应该显示 0x17700
    print(
        'OACP command: ${data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' ')}');
    return data;
  }

  Uint8List executeDisplayControl2(int screenNumber, int objectId) {
    int commandType = 0x04; // OACP的execute命令

    // 将screenNumber转换为2字节的数组（小端序）
    Uint8List screenBytes = Uint8List(2);
    screenBytes.buffer.asByteData().setUint16(0, screenNumber, Endian.little);

    // 将objectId转换为6字节的数组（小端序）
    Uint8List objectIdBytes = Uint8List(6);
    ByteData objectIdData = ByteData(8);
    objectIdData.setUint64(0, objectId, Endian.little);
    objectIdBytes.setRange(
        0, 6, objectIdData.buffer.asUint8List(0, 6)); // 小端序从第0字节开始取6字节

    // 创建合适大小的数据包（9字节）
    Uint8List data = Uint8List(9);
    data[0] = commandType; // 命令类型放在第一个字节
    data.setRange(1, 3, screenBytes); // screenNumber放在第1到第2字节
    data.setRange(3, 9, objectIdBytes); // objectId放在第3到第8字节

    return data;
  }

  Uint8List executeDisplayControl({
    required int screenAObjectId, // A屏对象ID，0表示不显示
    required int screenBObjectId, // B屏对象ID，0表示不显示
  }) {
    int commandType = 0x04; // OACP的execute命令

    // 计算总长度：1字节命令 + (2字节屏幕号 + 6字节对象ID) × 2
    Uint8List data = Uint8List(17);

    // 设置命令类型
    data[0] = commandType;

    // A屏配置（screenNumber = 0）
    data[1] = 0x00; // screenNumber低字节
    data[2] = 0x00; // screenNumber高字节
    // 写入A屏objectId（6字节，小端序）
    for (int i = 0; i < 6; i++) {
      data[3 + i] = (screenAObjectId >> (8 * i)) & 0xFF;
    }

    // B屏配置（screenNumber = 1）
    data[9] = 0x01; // screenNumber低字节
    data[10] = 0x00; // screenNumber高字节
    // 写入B屏objectId（6字节，小端序）
    for (int i = 0; i < 6; i++) {
      data[11 + i] = (screenBObjectId >> (8 * i)) & 0xFF;
    }
    return data;
  }

  void parseOPSResponse(List<int> value) {
    if (value.length >= 10) {
      final command = value[0];
      final offset = value.sublist(1, 5).reduce((a, b) => a + (b << 8));
      final length = value.sublist(5, 9).reduce((a, b) => a + (b << 8));
      final mode = value[9];

      print(
          'OPS Response: command=$command, offset=$offset, length=$length, mode=$mode');
    }
  }

  @override
  void onClose() {
    print('Controller closing...');
    _cleanupResources('Controller closing');
    WidgetsBinding.instance.removeObserver(this);
    super.onClose();
  }

  @override
  void dispose() {
    print('Controller dispose...');
    _cancelAllTransfers();
    Get.delete<CastProgressController>();
    super.dispose();
  }

  // 在开始新传输时调用
  Future<void> startNewTransfer(DeviceProgress device) async {
    final deviceId = device.deviceCachedInfo.id;
    // 确保清理旧的监控
    await _cancelProgressMonitoring(deviceId);
    // 重置进度
    device.progress.value = 0.0;
    // 其他初始化代码...
  }

  Future<void> _cleanupResources(String reason) async {
    if (_isDisposed) return; // 防止重复清理

    print('Cleaning up resources: $reason');
    _isDisposing = true;

    // 停止所有监控
    _isMonitoring.clear();

    // 取消所有定时器
    for (var timer in _progressSubscriptions.values) {
      timer.cancel();
    }
    _progressSubscriptions.clear();

    // 断开所有设备连接
    try {
      final connectedDevices = await FlutterBluePlus.connectedDevices;
      for (var device in connectedDevices) {
        try {
          print('Cleaning up: disconnecting device ${device.id}');
          await _closeL2capChannel(device);
          await device.disconnect();
          await Future.delayed(const Duration(milliseconds: 300));
        } catch (e) {
          print('Error during cleanup disconnect: $e');
        }
      }
    } catch (e) {
      print('Error getting connected devices during cleanup: $e');
    }
  }

  Future<bool> clearDevices(DeviceProgress device) async {
    BluetoothDevice? bluetoothDevice;
    try {
      // 1. 连接设备（包含重试逻辑）
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('connecting_device');
      bluetoothDevice = BluetoothDevice.fromId(device.deviceCachedInfo.id);

      for (int retry = 0; retry < MAX_RETRIES; retry++) {
        try {
          if (!bluetoothDevice.isConnected) {
            await bluetoothDevice.connect(timeout: CONNECT_TIMEOUT);
            bluetoothService
                    .deviceInfoMap[device.deviceCachedInfo.id.toString()] =
                bluetoothService
                    .deviceInfoMap[device.deviceCachedInfo.id.toString()]!
                    .copyWith(connectedTime: DateTime.now());
          }
          break;
        } catch (e) {
          if (retry == MAX_RETRIES - 1)
            throw Exception('连接失败，已重试$MAX_RETRIES次');
          device.status.value = AppLocalizations.of(Get.context!)!
              .translate('retrying_connection')
              .replaceAll('{count}', '${retry + 1}/$MAX_RETRIES');
          await Future.delayed(const Duration(seconds: 2));
        }
      }
      Uint8List displayCommand;
      if (device.deviceCachedInfo.displayInfo.length == 2) {
        displayCommand = executeDisplayControl(
          screenAObjectId: 0x000000000105,
          screenBObjectId: 0x000000000105,
        );
      } else {
        displayCommand = executeDisplayControl(
          screenAObjectId: 0x000000000105,
          screenBObjectId: 0x000000000000,
        );
      }
// 2. 发现服务
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('initializing_service');
      final services = await bluetoothDevice.discoverServices();

      final opsCharacteristic = services
          .expand((s) => s.characteristics)
          .firstWhere((c) => c.uuid.toString().toLowerCase() == '2ac5',
              orElse: () => throw Exception('找不到OPS特征值(2AC5)'));

      // 4. 设置特征值通知
      device.status.value = AppLocalizations.of(Get.context!)!
          .translate('initializing_notification');
      await opsCharacteristic.setNotifyValue(true);
      // 发送显示命令
      await opsCharacteristic.write(displayCommand);
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('success');

      return true;
    } catch (e) {
      print('传输错误: $e');
      device.status.value =
          AppLocalizations.of(Get.context!)!.translate('failed');
      return false;
    } finally {
      await bluetoothDevice?.disconnect();
    }
  }

  // Add this new method to disconnect all devices
  Future<void> _disconnectAllDevices() async {
    print('Disconnecting all previous Bluetooth connections');
    try {
      // Stop any ongoing scan
      if (FlutterBluePlus.isScanningNow) {
        await bluetoothService.stopScan();
      }

      try {
        await bluetoothService.cancelConnections();
      } catch (e) {
        print('Error canceling connections: $e');
      }
      // Get list of connected devices
      final connectedDevices = await FlutterBluePlus.connectedDevices;

      // Disconnect each device
      for (final device in connectedDevices) {
        try {
          print('Disconnecting device: ${device.id}');
          await _closeL2capChannel(device);
          await device.disconnect();
          await Future.delayed(const Duration(milliseconds: 300));
        } catch (e) {
          print('Error disconnecting device ${device.id}: $e');
        }
      }

      // Clear any stale connection references
      _activeTransfers.clear();
      _transferQueue.clear();

      print('All Bluetooth connections closed');
    } catch (e) {
      print('Error during disconnect all devices: $e');
    }
  }

  // 添加新方法来取消所有传输
  Future<void> _cancelAllTransfers() async {
    print('Cancelling all transfers...');

    // 清空传输队列
    _transferQueue.clear();

    // 断开所有活跃传输的设备
    final activeDeviceIds = List<String>.from(_activeTransfers);
    for (final deviceId in activeDeviceIds) {
      try {
        final device = BluetoothDevice.fromId(deviceId);
        await _closeL2capChannel(device);
        await device.disconnect();
      } catch (e) {
        print('Error cancelling transfer for device $deviceId: $e');
      }
    }
    _activeTransfers.clear();
  }
}

extension BluetoothDeviceExt on BluetoothDevice {
  static const platform = MethodChannel('flutter_blue_plus');

  Future<void> createL2capChannel(int psm) async {
    await platform.invokeMethod('createL2capChannel', {
      'deviceId': id.toString(),
      'psm': psm,
    });
  }

  Future<void> sendL2capData(Uint8List data) async {
    await platform.invokeMethod('sendL2capData', {
      'deviceId': id.toString(),
      'data': data,
    });
  }

  Future<Map<String, dynamic>> getL2capMtu(BluetoothDevice device) async {
    try {
      final result = await platform.invokeMethod('getL2capMtu', {
        'deviceId': id.toString(),
      });

      return Map<String, dynamic>.from(result);
    } catch (e) {
      rethrow;
    }
  }

  Future<void> closeL2capChannel() async {
    await platform.invokeMethod('closeL2capChannel', {});
  }
  // ... existing code ...
}

// 扩展 ByteData 以支持 Uint48
extension ByteDataExt on ByteData {
  void setUint48(int offset, int value, [Endian endian = Endian.big]) {
    // 确保值不超过 48 位
    value &= 0xFFFFFFFFFFFF;

    if (endian == Endian.little) {
      setUint16(offset, value & 0xFFFF, Endian.little);
      setUint16(offset + 2, (value >> 16) & 0xFFFF, Endian.little);
      setUint16(offset + 4, (value >> 32) & 0xFFFF, Endian.little);
    } else {
      setUint16(offset, (value >> 32) & 0xFFFF, Endian.big);
      setUint16(offset + 2, (value >> 16) & 0xFFFF, Endian.big);
      setUint16(offset + 4, value & 0xFFFF, Endian.big);
    }
  }
}

// 辅助方法：获取特征值的属性描述
String _getCharacteristicProperties(BluetoothCharacteristic c) {
  List<String> props = [];
  if (c.properties.read) props.add('读');
  if (c.properties.write) props.add('写');
  if (c.properties.writeWithoutResponse) props.add('无响应写');
  if (c.properties.notify) props.add('通知');
  if (c.properties.indicate) props.add('指示');
  if (c.properties.broadcast) props.add('广播');
  if (c.properties.authenticatedSignedWrites) props.add('认证签名写');
  if (c.properties.extendedProperties) props.add('扩展属性');
  if (c.properties.notifyEncryptionRequired) props.add('加密通知');
  if (c.properties.indicateEncryptionRequired) props.add('加密指示');
  return props.join(', ');
}

// 自定义异常类
class BluetoothDeviceDisconnectedException implements Exception {
  final String message;
  BluetoothDeviceDisconnectedException(this.message);

  @override
  String toString() => 'BluetoothDeviceDisconnectedException: $message';
}

class ProgressStuckException implements Exception {
  final String message;
  ProgressStuckException(this.message);

  @override
  String toString() => 'ProgressStuckException: $message';
}
